<?php
/**
 * Created by 张彪.
 * User: 小马出行
 * Date: 2018/3/6
 * Time: 14:50
 */
namespace my;
class Address
{
    const EARTH_RADIUS = 6378.137;
    const PI = 3.1415926535898;

    /**
     * 非高德坐标系转为高德坐标
     * @param $local //经度(lng--117)和纬度(lat--31)以,拼接成字符串
     * @param $coordsys
     * @return string
     * */
    public static function convert2GD($local,$coordsys='baidu')
    {
        $url="http://restapi.amap.com/v3/assistant/coordinate/convert?locations=$local&coordsys=$coordsys&output=json&key=".config('GD');
        $response = self::http_request($url);
        $result=json_decode($response, true);
        $local=$result['locations'];
        return $local;
    }

    /**
     * 根据高德坐标获取地理位置
     * @param $gd_local //经度(lng--117)和纬度(lat--31)以','拼接成字符串,批量查询时以'|'连接字符串,或是数组形式
     * @param $radius //搜索半径
     * @param $extensions //返回结果控制
     * @param $batch //batch=true为批量查询。batch=false为单点查询
     * @param $road_level //可选值：1，当road_level=1时，过滤非主干道路，仅输出主干道路数据
     * @return array
     * */
    public static function getAddressByGDLocal($gd_local,$radius=10,$extensions='base',$batch=false,$road_level=0)
    {
        $local = $gd_local;
        if(is_array($gd_local)&&!empty($gd_local)){
            $key_arr = array_keys($gd_local);
            if (count($gd_local)>20){
                return array('status'=>0,'msg'=>"批量查询最多支持20个坐标点");
            }
            $local = implode('|',$gd_local);
        }
        $radius = $radius?:10;
        $extensions = $extensions?'all':'base';
        $batch_ = $batch?'true':'false';
        $road_level = $road_level?1:0;
        $key = config('GD');
        $url = "http://restapi.amap.com/v3/geocode/regeo?output=json&location=$local&key=$key&radius=$radius&extensions=$extensions&batch=$batch_&roadlevel=$road_level";
        $response = self::http_request($url);
        $result = json_decode($response, true);
        if($result['infocode']!=10000){
            return array('status'=>0,'msg'=>config('gd_error_code')[$result['infocode']],'code'=>$result['infocode']);
        }
        $address = $result['regeocode']['addressComponent'];
        empty($address['township'])&&$address['township']='';
        $result['regeocode']['address'] = $address['province'].$address['city'].$address['district'].$address['township'];
        $data['result'] = $result['regeocode'];
        if($batch){
            $data['result'] = $result['regeocodes'];
            foreach ($data['result'] as $key => $val){
                $index = empty($key_arr) ? $key : $key_arr[$key];
                $address_b = $val['addressComponent'];
                empty($address_b['township'])&&$address_b['township']='';
                $data['result'][$index] = $val;
                $data['result'][$index]['address'] = $address_b['province'].$address_b['city'].$address_b['district'].$address_b['township'];
                if(!is_numeric($index))unset($data['result'][$key]);
            }
            unset($data['result'][0]);
        }
        return array('status'=>1,'data'=>$data['result']);
    }

    /**
     * 按照地址获取高德坐标
     * @param $address
     * @return array
     * */
    public static function getGDLocal($address)
    {
        $GD = config('GD');
        $url = "http://restapi.amap.com/v3/geocode/geo?address=$address&output=json&key=$GD";
        $response = self::http_request($url);
        $result = json_decode($response, true);
        if($result['infocode']!=10000){
            return array('data'=>'');
        }
        return array('data'=>$result['geocodes'][0]);
    }

    private static function http_request($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $response = curl_exec($ch); // 已经获取到内容，没有输出到页面上。
        curl_close($ch);
        return $response;
    }

    /**
     * 计算两组经纬度坐标 之间的距离
     * @param $lat1 //纬度1;
     * @param $lng1 //经度1;
     * @param $lat2 //纬度2;
     * @param $lng2 //经度2;
     * @param $len_type //(1:m or 2:km);
     * @param $decimal;//小数位
     * @return string m or km
     */
    public static function GetDistance($lat1, $lng1, $lat2, $lng2, $len_type = 1, $decimal = 0)
    {
        if(empty($lat1)||empty($lng1)||empty($lat2)||empty($lng2)){
            return false;
        }
        $radLat1 = $lat1 * self::PI / 180.0;
        $radLat2 = $lat2 * self::PI / 180.0;
        $a = $radLat1 - $radLat2;
        $b = ($lng1 * self::PI / 180.0) - ($lng2 * self::PI / 180.0);
        $s = 2 * asin(sqrt(pow(sin($a/2),2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2),2)));
        $s = $s * self::EARTH_RADIUS;
        $s = round($s * 1000);
        if ($len_type > 1)
        {
            $s /= 1000;
            $decimal = $decimal?:3;
        }
        return round($s, $decimal);
    }

    private static function GetRange($lat,$lon,$raidus){
        //计算纬度
        $degree = (24901 * 1609) / 360.0;
        $dpmLat = 1 / $degree;
        $radiusLat = $dpmLat * $raidus;
        $minLat = $lat - $radiusLat; //得到最小纬度
        $maxLat = $lat + $radiusLat; //得到最大纬度
        //计算经度
        $mpdLng = $degree * cos($lat * (self::PI / 180));
        $dpmLng = 1 / $mpdLng;
        $radiusLng = $dpmLng * $raidus;
        $minLng = $lon - $radiusLng;  //得到最小经度
        $maxLng = $lon + $radiusLng;  //得到最大经度
        //范围
        $range = array(
            'minLat' => $minLat,
            'maxLat' => $maxLat,
            'minLon' => $minLng,
            'maxLon' => $maxLng
        );
        return $range;
    }
}